package com.lb.pdm.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.lb.pdm.common.constants.RedisConstants;
import com.lb.pdm.common.exceptions.MyCustomException;
import com.lb.pdm.common.result.GraceJSONResult;
import com.lb.pdm.common.result.ResponseStatusEnum;
import com.lb.pdm.entity.HouseholdInfo;
import com.lb.pdm.entity.HouseholdMember;
import com.lb.pdm.entity.PersonInfo;
import com.lb.pdm.entity.SysUser;
import com.lb.pdm.entity.bo.HouseholdInfoBO;
import com.lb.pdm.entity.bo.HouseholderBO;
import com.lb.pdm.entity.vo.HouseholdInfoVO;
import com.lb.pdm.entity.vo.HouseholdInfoVO2;
import com.lb.pdm.mapper.HouseholdInfoMapper;
import com.lb.pdm.mapper.HouseholdMemberMapper;
import com.lb.pdm.mapper.PersonInfoMapper;
import com.lb.pdm.service.HouseholdInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 户籍信息表 服务实现类
 * </p>
 *
 * @author pdm
 * @since 2025-10-29
 */
@Service
public class HouseholdInfoServiceImpl extends ServiceImpl<HouseholdInfoMapper, HouseholdInfo> implements HouseholdInfoService {
    @Autowired
    private PersonInfoMapper personInfoMapper;
    @Autowired
    private HouseholdInfoMapper householdInfoMapper;
    @Autowired
    private HouseholdMemberMapper householdMemberMapper;;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public GraceJSONResult registerHousehold(HouseholdInfoBO householdInfoBO, String token) {
        LambdaQueryWrapper<PersonInfo> personQuery = new LambdaQueryWrapper<>();
        personQuery.eq(PersonInfo::getIdCard, householdInfoBO.getIdCard());
        PersonInfo personInfo = personInfoMapper.selectOne(personQuery);

        LambdaQueryWrapper<HouseholdInfo> householdQuery = new LambdaQueryWrapper<>();
        householdQuery.eq(HouseholdInfo::getHouseholderId, personInfo.getId());
        HouseholdInfo existingHouseholdInfo = householdInfoMapper.selectOne(householdQuery);

        if (existingHouseholdInfo != null) {
            return GraceJSONResult.errorMsg("该用户已注册户籍");
        }

        LambdaQueryWrapper<HouseholdMember> householdMemberQuery = new LambdaQueryWrapper<>();
        householdMemberQuery.eq(HouseholdMember::getPersonId, personInfo.getId())
                .eq(HouseholdMember::getStatus, 1);
        HouseholdMember originMember = householdMemberMapper.selectOne(householdMemberQuery);

        // 开始生成户籍号
        String sysuserString = redisTemplate.opsForValue().get(RedisConstants.USER_TOKEN_PREFIX + token);
        if (sysuserString == null || sysuserString.isEmpty()) {
            throw new MyCustomException(ResponseStatusEnum.SYSUSER_NOT_LOGIN);
        }

        // 获得派出所所在辖区代号
        SysUser sysUser = JSON.parseObject(sysuserString, SysUser.class);
        String stationCode = sysUser.getStationCode();

        if (originMember != null) {
            LambdaUpdateWrapper<HouseholdMember> householdMemberUpdate = new LambdaUpdateWrapper<>();
            householdMemberUpdate.eq(HouseholdMember::getId, originMember.getId())
                    .set(HouseholdMember::getStatus, 0) // 0 表示 "已迁出"
                    .set(HouseholdMember::getLeaveDate, new Date())
                    .set(HouseholdMember::getLeaveReason, "分户立户")
                    .set(HouseholdMember::getUpdateTime, new Date())
                    .set(HouseholdMember::getUpdateBy, sysUser.getId());

            int i = householdMemberMapper.update(null, householdMemberUpdate);
            if (i <= 0) {
                // 如果更新失败，事务回滚
                return GraceJSONResult.errorMsg("更新原户籍成员状态失败");
            }
        }

        HouseholdInfo householdInfo = new HouseholdInfo();
        BeanUtils.copyProperties(householdInfoBO, householdInfo);


        // 获得辖区下的流水号
        String sequence = redisTemplate.opsForValue().get(RedisConstants.HOUSEHOLD_SEQUENCE_PREFIX + stationCode);

        // 这是解决并发问题的关键。INCR是原子操作。
        // 如果两个请求同时到达，Redis会确保它们一个返回 "1"，一个返回 "2"，绝不会重复。
        String sequenceKey = RedisConstants.HOUSEHOLD_SEQUENCE_PREFIX + stationCode;
        Long newSequence = redisTemplate.opsForValue().increment(sequenceKey);

        // 假设流水号为7位，不足则在左侧补0
        String sequenceString = String.format("%07d", newSequence);
        String householdNumber = stationCode + "-" + sequenceString; // e.g., "310101-0000001"

        // 结束生成户籍号

        householdInfo.setHouseholdNumber(householdNumber);
        householdInfo.setHouseholderId(personInfo.getId());
        householdInfo.setRegisterDate(new Date());
        householdInfo.setStatus((byte)1);
        householdInfo.setCreateTime(new Date());
        householdInfo.setUpdateTime(new Date());
        householdInfo.setCreateBy(sysUser.getId());
        householdInfo.setUpdateBy(sysUser.getId());

        int insertResult = householdInfoMapper.insert(householdInfo);
        if (insertResult <= 0) {
            return GraceJSONResult.errorMsg("创建户籍信息失败");
        }


        HouseholdMember newMember = new HouseholdMember();
        newMember.setHouseholdId(householdInfo.getId());
        newMember.setPersonId(personInfo.getId());
        newMember.setRelationship("户主");
        newMember.setJoinDate(new Date());
        newMember.setJoinReason("立户");
        newMember.setStatus((byte)1);
        newMember.setCreateTime(new Date());
        newMember.setUpdateTime(new Date());
        newMember.setCreateBy(sysUser.getId());
        newMember.setUpdateBy(sysUser.getId());

        int insertMemberResult = householdMemberMapper.insert(newMember);
        if (insertMemberResult <= 0) {
            return GraceJSONResult.errorMsg("创建户籍成员失败");
        }

        return GraceJSONResult.ok();
    }

    @Override
    public List<HouseholdInfoVO> queryHouseholder(HouseholderBO householderBO) {
        int start = (householderBO.getPageNum() - 1) * householderBO.getPageSize();

        return householdInfoMapper.listHouseholders(
                householderBO.getName(),
                householderBO.getIdCard(),
                householderBO.getAddress(),
                start,
                householderBO.getPageSize()
        );
    }

    @Override
    public HouseholdInfoVO2 getPersonHousehold(Long personId) {
        System.out.println("DEBUG: 开始查询人员户籍信息, personId = " + personId);
        HouseholdInfoVO2 result = householdInfoMapper.getPersonHousehold(personId);
        System.out.println("DEBUG: 查询结果 = " + result);
        if (result != null) {
            System.out.println("DEBUG: 户籍ID = " + result.getId() + ", 类型 = " + (result.getId() != null ? result.getId().getClass().getName() : "null"));
            System.out.println("DEBUG: 户号 = " + result.getHouseholdNumber());
            System.out.println("DEBUG: 户主姓名 = " + result.getName());
            System.out.println("DEBUG: 地址 = " + result.getAddress());
        }
        return result;
    }
}
